package br.fot.granola.oboe.parsers;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import br.fot.granola.oboe.graphics.Backend;
import br.fot.granola.oboe.graphics.backend.VoxelBackend;
import br.fot.granola.oboe.util.Vector;

public class BitmapVoxelParser extends Parser
{
	private class Header {
		public Vector size = new Vector();
		public int start;
	}
	
	private Header header = new Header();
	private boolean[] bits;
	
	private void readBits( ByteBuffer buf, int pos, int size )
	{
		int fb = header.start + (int) Math.floor( pos / 8 );
		int off = pos % 8;
		int bitsRead = 0;
		int d;
		while( bitsRead < size )
		{
			d = buf.getInt( fb );
			fb += 4;
			
			for( int i = off; bitsRead < size && i < 32; bitsRead++, i++ )
			{
				bits[bitsRead] = ((d>>i) & 1) == 1;
			}
			
			off = 0;
		}
	}
	
	public Backend run( Object data ){
		Backend back = new VoxelBackend();
		ByteBuffer buf = (ByteBuffer) data;
		int bpv; // bits per voxel
		
		buf.order( ByteOrder.LITTLE_ENDIAN );
		buf.position(0);
		header.start = buf.getInt();
		bpv = buf.getInt();
		header.size.readInt( buf );
		
		buf.position( header.start );
		if( header.size.x * header.size.y * header.size.z * bpv != buf.remaining() * 8 ) return null;
		this.bits = new boolean[bpv];
		
		for( int x=0; x<header.size.x; ++x )
		{
			for( int y=0; y<header.size.y; ++y )
			{
				for( int z=0; z<header.size.z; ++z )
				{
					this.readBits( buf, (int) ((z*header.size.x*header.size.y) * (y*header.size.x) + x) * bpv, bpv );
					
				}
			}
		}
		
		return back; 
	}
	

}
